package com.zjjh.algorithm;

import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yunhe
 */
@Component
public class DbComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<String> {

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<String> shardingValue) {
        Map<String, Collection<String>> data = shardingValue.getColumnNameAndShardingValuesMap();
        List<String> idColl = (List<String>) data.get("id");
        List<String> codeColl = (List<String>) data.get("id_code");
        if (idColl == null && codeColl == null) {
            throw new UnsupportedOperationException();
        }
        List<Integer> codeNum = codeColl != null ? codeColl.stream().map(e -> Integer.valueOf(StringUtils.substring(e, 8))).collect(Collectors.toList()) : null;
        List<Integer> idNum = idColl != null ? idColl.stream().map(e -> Integer.valueOf(StringUtils.substring(e, 15))).collect(Collectors.toList()) : null;
        List<Integer> nums = null;

        if (codeColl != null && idColl != null) {
            String codeStr = StringUtils.join(codeColl);
            String idStr = StringUtils.join(idColl);
            if (!codeStr.equals(idStr)) {
                throw new UnsupportedOperationException();
            }
        }
        nums = idNum != null ? idNum : codeNum;
        Set<String> target = new HashSet<>();
        for (Integer num : nums) {
            for (String key : availableTargetNames) {
                if (key.endsWith(String.valueOf(num % availableTargetNames.size()))) {
                    target.add(key);
                    break;
                }
            }
        }
        if (target == null){
            throw new UnsupportedOperationException();
        }
        return target;
    }


    @Override
    public Properties getProps() {
        return null;
    }

    @Override
    public void init(Properties props) {

    }
}

